/*
 * Created by 2006-7-21 上午12:53:55
 * $Id$
 */
package com.someok.web.listener;

import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.lang.StringUtils;
import org.hsqldb.Server;

/**
 * 
 * <p>
 * <a href="HsqlListener.java.html"><i>View Source</i></a>
 * </p>
 * 
 * @author wjx
 * @version $Revision$ $Date$
 */
public class HsqlListener implements ServletContextListener {

	Server hsqlServer = new Server();

	private Properties loadProperties() throws IOException {
		Properties prop = new Properties();
		prop.load(getClass().getResourceAsStream("/init.properties"));
		return prop;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
	 */
	public void contextDestroyed(ServletContextEvent event) {
		logInfo("准备关闭HSQL数据库...");
		int hStop = hsqlServer.stop();
		logInfo("HSQL数据库关闭成功[" + hStop + "]...");

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
	 */
	public void contextInitialized(ServletContextEvent event) {
		logInfo("初始化 HSQL 数据库......");
		Properties prop = null;
		try {
			prop = loadProperties();
		} catch (IOException e1) {
			throw new RuntimeException(e1);
		}

		// 数据库路径
		String databasePath = prop.getProperty("hsqldb.server.database");
		// 数据库别名
		String databaseName = prop.getProperty("hsqldb.server.dbName");
		// 是否在控制台输出信息
		String silentString = prop.getProperty("hsqldb.server.isSilent");
		// 是否控制isSilent所无法屏蔽的语句
		String silentOther = prop.getProperty("hsqldb.server.silentOther");

		if (databasePath == null) {
			throw new RuntimeException("数据库路径为空，无法定位数据库位置！");
		} else {
			// 数据库路径不为空则需替换${ctxPath}为应用的实际路径
			// 如果没有找到${ctxPath}，则保持原状
			if (databasePath.indexOf("${ctxPath}") != -1) {
				databasePath = StringUtils.replace(databasePath, "${ctxPath}",
						getWebAppBasePath(event));
			}
		}

		if (databaseName == null) {
			throw new RuntimeException("数据库名字为空");
		}

		boolean isSilent = true;
		if (!"true".equalsIgnoreCase(silentString)) {
			isSilent = false;
		}

		// 必须放在前面设置，否则下面的两个set方法中会有些语句输出
		hsqlServer.setSilent(isSilent);
		// setSilent设置为true之后，仍然会有些语句输出到控制台上（用的PrintWriter）。
		// 下面的语句可以屏蔽这些输出
		if ("true".equalsIgnoreCase(silentOther)) {
			hsqlServer.setLogWriter(null);
		}

		hsqlServer.setDatabasePath(0, databasePath);
		hsqlServer.setDatabaseName(0, databaseName);

		hsqlServer.start();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		logInfo("HSQL 数据库启动成功！");
		logInfo("--------------------------------------------------------------");

	}

	private String getWebAppBasePath(ServletContextEvent event) {
		String result = event.getServletContext().getRealPath("/");
		// 部分web服务器在此处的解析有所不同
		if (result.endsWith("/")) {
			result = StringUtils.chop(result);
		}
		return result;
	}

	private void logInfo(String string) {
		System.out.println("[HSQL]" + string);
	}
}
